package hotel.base.oversea.utils.redis;

import hotel.base.oversea.config.PropertyUtil;
import hotel.base.oversea.constant.CommonBaseConstants;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

@Slf4j
public class RedisPoolUtil {
    private static JedisSentinelPool pool = null;

    //redis 哨兵相关
    public static String redisMasterName= PropertyUtil.getProperty("common.redis.masterName");
    public static String redisSentinel1= PropertyUtil.getProperty("common.redis.sentinel_1");
    public static String redisSentinel2= PropertyUtil.getProperty("common.redis.sentinel_2");
    public static String redisSentinel3= PropertyUtil.getProperty("common.redis.sentinel_3");
    public static String redisPass= PropertyUtil.getProperty("common.redis.pass");

    // 可用连接实例的最大数目，默认值为8；
    // 如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
    private static int MAX_ACTIVE = 1024;

    // 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
    private static int MAX_IDLE = 200;

    // 等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
    private static int MAX_WAIT = 10000;

    // 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
    private static boolean TEST_ON_BORROW = true;


    /**
     *  <p>Description: 获取jedispool 连接池 </p>
     */
    private static JedisSentinelPool getPool() {
        if (pool == null) {
            log.info("进入getPool >>>>> pool is null!!");
            JedisPoolConfig config = new JedisPoolConfig();
            //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
            //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
            config.setMaxTotal(MAX_ACTIVE);
            //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
            config.setMaxIdle(MAX_IDLE);
            //表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
            config.setMaxWaitMillis(MAX_WAIT);


            Set<String> sentinelSet =new HashSet<String>();
            sentinelSet.add(redisSentinel1);
            sentinelSet.add(redisSentinel2);
            sentinelSet.add(redisSentinel3);


            pool = new JedisSentinelPool(redisMasterName,sentinelSet,config);
        }
        return pool;
    }

    public static void returnResource(JedisSentinelPool pool, Jedis jedis) {
        if (jedis != null) {
            jedis.close();
//            pool.close();
        }
    }


    public static Jedis getJedis() throws Exception {
        Jedis jedis = null;
        pool = getPool();
        jedis = pool.getResource();
        jedis.auth(redisPass);
        return jedis;
    }

    public static String get(int db,String key) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = getJedis();
            if(db > 16 || db < 0){
                db = 0;
            }
            jedis.select(db);
            value = jedis.get(key);
        } catch (Exception e) {
            if (jedis != null) {
                jedis.close();
            }
            e.printStackTrace();
        } finally {
            returnResource(pool, jedis);
        }
        return value;
    }

    public static String set(int db,String key, String value) {
        Jedis jedis = null;
        String ans = null;
        try {
            jedis = getJedis();
            if(db > 16 || db < 0){
                db = 0;
            }
            jedis.select(db);
            ans = jedis.set(key, value);
        } catch (Exception e) {
            //释放redis对象
            if (jedis != null) {
                jedis.close();
            }
            e.printStackTrace();
        } finally {
            //返还到连接池
            returnResource(pool, jedis);
        }
        return ans;
    }

    public static String setex(int db,String key, String value, int seconds) {
        Jedis jedis = null;
        String ans = null;
        try {
            jedis = getJedis();
            if(db > 16 || db < 0){
                db = 0;
            }
            jedis.select(db);
            ans = jedis.setex(key, seconds, value);
        } catch (Exception e) {
            if (jedis != null) {
                jedis.close();
            }
            e.printStackTrace();
        } finally {
            //返还到连接池
            returnResource(pool, jedis);
        }
        return ans;
    }


    public static void main(String[] args) {
        int num = 5;
        for (int i=0;i<num;i++) {
            RedisPoolUtil.setex(CommonBaseConstants.REDIS_DB_5, "tea111_"+i, "1111_"+i, 100);
        }


    }
}
